home *** CD-ROM | disk | FTP | other *** search
-
- /* --- C ---
- ************************************************************************
- *
- * Filename : header.c
- * Description : Analysation of MPEG-Headers
- * Part of : SECMPEG
- *
- * Version : 1.0
- * Language : C
- * For machine : SunOS 4.1.x, INTERACTIVE Unix 2.2.1, Linux, MS-DOS
- * Compile as : see Makefile
- *
- * Authors : Juergen Meyer, Frank Gadegast
- * Contact : jm@cs.tu-berlin.de, phade@cs.tu-berlin.de
- *
- ************************************************************************
- */
-
- #include <stdio.h>
- #include "defs.h"
- #include "marker.h"
- #include "header.h"
- #include "qtables.h"
-
- /* ------ PUBLIC ------ */
-
- int ReadHeader(void); /* !!!!!!!!!!!!!!! */
- void ReadHeaderTrailor(); /* alle Funktionen */
- int ClearToHeader(); /* operieren auf dem */
- int ReadVideoSequenceHeader(); /* FrameBuffer, d.h. keine*/
- void ReadGroupOfPicturesHeader(); /* direkte io-operationen */
-
- int ReadPictureHeader();
- void ReadSliceHeader();
- int ReadMakroblockHeader();
-
-
-
- /* ------ PRIVAT ------ */
-
- static INT DecodeMV(INT,INT);
-
- /* ------ IMPORT ------ */
-
- extern void readalign();
- extern int CheckEOF();
-
- extern int GetnBit(int); /* decode.c */
- extern int GetBit();
- extern void bytealign();
-
-
-
- extern INT Decode(DHUFF *); /* huff.c */
-
- extern long total_bytes_read; /* stream.c */
- extern INT bit_set_mask[];
-
- extern INT csize[]; /* huff.h */
- extern DHUFF *MBADHuff;
- extern DHUFF *MVDDHuff;
- extern DHUFF *CBPDHuff;
- extern DHUFF *T1DHuff;
- extern DHUFF *T2DHuff;
- extern DHUFF *IntraDHuff;
- extern DHUFF *PredictedDHuff;
- extern DHUFF *InterpolatedDHuff;
- extern DHUFF *DCLumDHuff;
- extern DHUFF *DCChromDHuff;
- extern DHUFF **ModuloDHuff;
-
- /* -------------------------------------------- */
-
- int ReadHeader(void)
- {
- INT retval;
-
- #ifdef DEBUG
- fprintf(stderr,"ReadHeader\n");
- #endif
-
- readalign();
- if ((retval = GetnBit(MBSC_LENGTH)) != MBSC)
- {
- while(!retval)
- {
- if ((retval = GetnBit(8)) == MBSC)
- return(0);
- else if(retval && (CheckEOF()))
- {
- #ifdef DEBUG
- fprintf(stderr," %s\n"," End of File ");
- #endif
- error_exit(0);
- }
- }
- #ifdef DEBUG
- fprintf(stderr,"Bad input read: %d\n",retval);
- #endif
- return(-1);
- }
- return(0);
- }
-
-
-
- void ReadHeaderTrailer()
- {
-
- INT trailor_val;
-
- #ifdef DEBUG
- fprintf(stderr,"ReadHeaderTrailor\n");
- #endif
-
- while(TRUE)
- {
- trailor_val = GetnBit(8);
- switch(trailor_val)
- {
- case 0:
- MBSRead = -1;
- return;
- case GOPSC :
- MBSRead = -2;
- return;
- case VSEC:
- MBSRead = -3;
- return;
- case VSSC:
- MBSRead = -4;
- return;
- case UDSC:
- #ifdef DEBUG
- fprintf(stderr,"User data code found.\n");
- #endif
- ClearToHeader();
- break;
-
- case EXSC:
- #ifdef DEBUG
- fprintf(stderr,"Extension data code found.\n");
- #endif
- ClearToHeader();
- break;
-
- default: if ((trailor_val > 0) && (trailor_val < 0xb0))
- {
- MBSRead = trailor_val-1;
- SVP = trailor_val;
- }
- return;
- }
- }
- }
-
-
-
- int ClearToHeader()
- {
-
- INT input;
-
- #ifdef DEBUG
- fprintf(stderr,"ClearToHeader\n");
- #endif
-
- readalign();
- if ((input = GetnBit(MBSC_LENGTH)) != MBSC)
- {
- do
- {
- if (CheckEOF())
- error_exit(ERROR_PREMATURE_EOF);
-
- input = input & 0xffff;
- input = (input << 8) | GetnBit(8);
- }
- while (input != MBSC);
- }
- return(0);
- }
-
-
-
- int ReadVideoSequenceHeader()
- {
- INT i;
-
- #ifdef DEBUG
- fprintf(stderr,"ReadVideoSequenceHeader\n");
- #endif
-
- HorizontalSize = GetnBit(12);
- VerticalSize = GetnBit(12);
- Aprat = GetnBit(4);
-
- if ((!Aprat)||(Aprat==0xf))
- return(ERROR_ASPECT_RATIO);
- Prate = GetnBit(4);
-
- if ((!Prate) || (Prate > 8))
- return(ERROR_PICTURE_RATE);
-
- Brate = GetnBit(18);
- if (!Brate)
- return(ERROR_BIT_RATE);
- if (Brate == 0x3fff)
- Rate=0;
- else
- Rate = Brate*400;
-
- (void) GetBit();
-
- Bsize = GetnBit(10);
- BufferSize = Bsize*16*1024;
-
- ConstrainedParameterFlag = GetBit();
-
- LoadIntraQuantizerMatrix = GetBit();
-
- if(LoadIntraQuantizerMatrix)
- for( i = 0; i < BLOCKSIZE;i++)
- MPEGIntraQ[i] = GetnBit(8);
-
- LoadNonIntraQuantizerMatrix = GetBit();
- if(LoadNonIntraQuantizerMatrix)
- for( i = 0; i < BLOCKSIZE;i++)
- MPEGNonIntraQ[i] = GetnBit(8);
-
- return(0);
- }
-
- void ReadGroupOfPicturesHeader()
- {
-
- #ifdef DEBUG
- fprintf(stderr,"%s : %d\n","ReadGroupOfPicturesHeader",groupofpictures_count++);
- #endif
-
- TimeCode = GetnBit(25);
- ClosedGOP = GetBit();
- BrokenLink = GetBit();
- }
-
-
-
- /* -------------------------------------------------------- */
-
- int ReadPictureHeader()
- {
-
- #ifdef DEBUG
- fprintf(stderr,"ReadPictureHeader\n");
- #endif
- bytealign();
- TemporalReference = GetnBit(10);
- PType = GetnBit(3);
-
- if(!PType)
- return(ERROR_FRAME_TYPE);
-
- BufferFullness = GetnBit(16);
-
- if ((PType == P_PREDICTED) || (PType == P_INTERPOLATED))
- {
- FullPelForward = GetBit();
- ForwardIndex = GetnBit(3);
- }
- if (PType == P_INTERPOLATED)
- {
- FullPelBackward = GetBit();
- BackwardIndex = GetnBit(3);
- }
- PictureExtra=0;
- while(GetBit())
- {
- PictureExtraInfo = GetnBit(8);
- PictureExtra = 1;
- }
-
- return(PType);
- }
-
- /* -------------------------------------------------------- */
-
- void ReadSliceHeader()
- {
- #ifdef DEBUG
- fprintf(stderr,"%s : %d\n","ReadSliceHeader",sliceheader_count++);
- #endif
-
- SQuant = GetnBit(5);
- for(SliceExtra=0;GetBit();)
- {
- SliceExtraInfo = GetnBit(8);
- SliceExtra = 1;
- }
- }
-
- int ReadMakroBlockHeader()
- {
- INT Readin;
-
- #ifdef DEBUG
- fprintf(stderr,"%s : %d\n","ReadMakroBlockHeader",current_makroblock);
- #endif
-
- current_makroblock++;
-
- for(MBAIncrement=0;;)
- {
- do
- {
- Readin = Decode(MBADHuff);
- }
- while(Readin == 34);
- if (Readin < 34)
- {
- MBAIncrement += Readin;
- break;
- }
- else if (Readin == 36)
- {
- while(!GetBit());
- return(-1);
- }
- else if (Readin == 35)
- MBAIncrement += 33;
- else
- {
- #ifdef DEBUG
- fprintf(stderr,"Bad MBA Read: %d \n",Readin);
- #endif
- fprintf(stderr,"Bad MBA Read: %d \n",Readin);
-
- break;
- }
- }
- switch(PType)
- {
- case P_INTRA:
- MType = Decode(IntraDHuff);
- break;
- case P_PREDICTED:
- if (MBAIncrement > 1) MVD1H=MVD1V=0;
- MType = Decode(PredictedDHuff);
- break;
- case P_INTERPOLATED:
- MType = Decode(InterpolatedDHuff);
- break;
- case P_DCINTRA:
- if (!GetBit())
- {
- #ifdef DEBUG
- fprintf(stderr,"Expected one bit for DC Intra, 0 read.\n");
- #endif
- fprintf(stderr,"Expected one bit for DC Intra, 0 read.\n");
- }
- break;
- default:
- #ifdef DEBUG
- fprintf(stderr,"Bad picture type.\n");
- #endif
- fprintf(stderr,"Bad picture type.\n");
- break;
- }
- if (QuantPMType[PType][MType]) MQuant=GetnBit(5);
- if (MFPMType[PType][MType])
- {
- if (FullPelForward)
- {
- MVD1H = DecodeMV(ForwardIndex,MVD1H/2)<<1;
- MVD1V = DecodeMV(ForwardIndex,MVD1V/2)<<1;
- }
- else
- {
- MVD1H = DecodeMV(ForwardIndex,MVD1H);
- MVD1V = DecodeMV(ForwardIndex,MVD1V);
- }
- }
- else if (PType==P_PREDICTED)
- MVD1H=MVD1V=0;
-
- if (MBPMType[PType][MType])
- {
- if (FullPelBackward)
- {
- MVD2H = DecodeMV(BackwardIndex,MVD2H/2)<<1;
- MVD2V = DecodeMV(BackwardIndex,MVD2V/2)<<1;
- }
- else
- {
- MVD2H = DecodeMV(BackwardIndex,MVD2H);
- MVD2V = DecodeMV(BackwardIndex,MVD2V);
- }
- }
- if (CBPPMType[PType][MType]) CBP = Decode(CBPDHuff);
- else if (IPMType[PType][MType]) CBP=0x3f;
- else CBP=0;
- return(0);
- }
-
-
- static INT DecodeMV(INT fd,INT oldvect)
- {
- INT r,v,limit;
-
- #ifdef MV_DEBUG
- fprintf(stderr,"DecodeMV\n");
- getch();
- #endif
-
- limit = 1 << (fd+3);
- v = Decode(MVDDHuff);
- if (v)
- {
- if (v > 16) {v = v-33;} /* our codes are positive, negative vals */
- /* are greater than 16. */
- fd--; /*Find out number of modulo bits=fd */
- if (fd)
- {
- r = GetnBit(fd); /* modulo lower bits */
- if (v > 0)
- v = (((v-1)<<fd)|r)+1; /* just "or" and add 1 for dead band. */
- else
- v = ((v+1)<<fd)+(-1^r); /* Needs mask to do an "or".*/
- }
- if (v==limit)
- {
- #ifdef MV_DECODE
- fprintf(stderr,"Warning: motion vector at positive limit.\n");
- #endif
- }
- }
- v += oldvect; /* DPCM */
- if (v < -limit)
- v += (limit << 1);
- else if (v >= limit)
- v -= (limit << 1);
- if (v==limit)
- {
- #ifdef MV_DEBUG
- fprintf(stderr,"Apparently illegal reference: (MV %d) (LastMV %d).\n",v,oldvect);
- #endif
- }
- return(v);
- }
-